<?php
session_start();
include 'config.php';
include 'data_provider.php';
$user_logged=$_SESSION['auth'];

$jqalendar = new Jqalendar($data_provider,$config,$user_logged);
switch($_GET['a'])
{
	case 'delete_event':
		$jqalendar->delete_event($_GET['id']);
	break;
	case 'edit_event':
		$jqalendar->edit_event($_POST['event'],$_POST['repeated_event']);
	break;
	case 'move_event':
		$jqalendar->move_event($_GET['id'],$_GET['date_ymd'],$_GET['view'],$_GET['year'],$_GET['month']);
	break;
	case 'get_events':
		$jqalendar->get_events($_GET['view'],$_GET['year'],$_GET['month'],$_GET['day']);
	break;
	case 'add_calendar':
		$jqalendar->add_calendar($_POST['name'],$_POST['bgcolor'],$_POST['textcolor']);
	break;
	case 'get_calendars':
		$jqalendar->get_calendars();
	break;

}

class Jqalendar {
	var	$data_provider ;
	var $config;
	var $user_logged; /* false or 
	                         * array('id'=>'',
	                         * 		'username'=>'',
	                         * 		'alias'=>'') 
	                         * */

	
							
	function Jqalendar($data_provider,$config,$user_logged=false)
	{
		$this->data_provider=&$data_provider;
		
		$this->config=$config;
		$this->user_logged=$user_logged;
		if($user_logged)$this->data_provider->setUserId($user_logged['id']);
		else die('{"error":"login_required"}');
		
	}
	

	/*
	* Scarica gli eventi
	*
	*/
	
	function get_events($view = '', $year = '', $month = '', $day = '')
	{
		//die(mktime(23,30,0,1,1,2008)."....".mktime(23,30,00,1,2,2008));
		$data_provider= &$this->data_provider;
		
		
		if ($view == null) return false;
		
		switch ($view)
		{
			case "month":

				// Calcolo unixtime della data di partenza e della data di fine (ultimo giorno del mese, vedi manuale php)
				
				/**
				 * 
				$previous_month = $this->_get_previous_month($year,$month);
				$next_month = $this->_get_next_month($year,$month);
				$datestart=mktime(0,0,0,$previous_month[1],'1',$previous_month[0]);
				$dateend=mktime(24,0,0,$next_month[1]+1,0,$next_month[0]);			
*/				
				//$server_gmt_offset=-date("Z")/60;
				
				$datestart=gmmktime(0,0,0,$month,-7,$year);			
				$datefinish=gmmktime(0,0,0,$month,38,$year);
				
				// Scaricamento eventi
				$events = $data_provider->get_events($datestart,$datefinish,'month');	
				$events_repeat = $data_provider->get_repeated_events($datestart,'month');
									
				$duration = floor(($datefinish-$datestart) / ONE_DAY)+1;
				
				$y=gmdate('Y',$datestart);
				$m=gmdate('m',$datestart);
				$d=gmdate('d',$datestart);

				for ($i = 1; $i <= $duration; $i++)
				{	
					
					$dateunix = gmmktime(0,0,0,$m,$i+(int)$d,$y);
					$dateymd = gmdate("Ymd",$dateunix);
					
					// eventi ripetuti
					if(!is_null($events_repeat))
					foreach ($events_repeat as $item) 
					{
						$item['start']=$this->_expandDate($item['start']);
						$item['finish']=$this->_expandDate($item['finish']);
						$item['repeat_finish']=$this->_expandDate($item['repeat_finish']);
						
						if ($this->repeated_events_matches_date($item,$dateunix))
						{

							$item['day_parts']=$this->_getEventDayParts($item);
							$item['repeat']=true;
							$item['events_repeat']=array('type'=>$item['type'],'repeat_finish'=>$item['repeat_finish'],'frequency'=>$item['frequency'],'days'=>$item['days']);
							unset($item['type'],$item['repeat_finish'],$item['frequency'],$item['days']);
							$events_output['events'][$item['id']]=$item;
							
							$tmp_unix=$dateunix;
							for($j=1;$j<=$item['day_parts'];$j++){
								$events_output['match'][gmdate("Ymd",$tmp_unix)][] = $item['id'];
								$tmp_unix=$tmp_unix+ONE_DAY;
							}
						}				
					}
					
					
					
					//eventi non ripetuti
					if(!is_null($events))
					foreach($events as $item)
					{
						
						$item['start']=$this->_expandDate($item['start']);
						$item['finish']=$this->_expandDate($item['finish']);
						$item['day_parts']=$this->_getEventDayParts($item);
						
						$item['repeat']=false;
						if ($item['allday'] == 1) {								
							if ($item['start']['ymd'] <= $dateymd && $item['finish']['ymd'] >= $dateymd  )
							{
								// creazione array match
								if(!is_array($events_output['match'][$dateymd]) || !in_array($item['id'],$events_output['match'][$dateymd]))
								{
									$events_output['match'][$dateymd][] = $item['id'];
									$events_output['events'][$item['id']]=$item;
								}
							} 
						} else {
							if(($item['start']['unix'] <= $dateunix && $item['finish']['unix'] > $dateunix ) || ($item['start']['unix']>= $dateunix  && $item['start']['unix'] < $dateunix+ONE_DAY))
							{					
								// creazione array match
								if(!is_array($events_output['match'][$dateymd]) || !in_array($item['id'],$events_output['match'][$dateymd]))
								{
									$events_output['match'][$dateymd][] = $item['id'];
									$events_output['events'][$item['id']]=$item;
								}
							}							
						}
					}	
					//if($dateymd=='20080520')debug($item);//debug($events_output['match']['20080520']);			
				}	
				
				echo json_encode($events_output);
								
			break;
			
		}		
	}
	
	function repeated_events_matches_date($event,$date)
	{
		/**
		 * Array containing the number of days in each month in a non-leap year
		 *
		 * @global array $days_per_month
		 */
		$days_per_month = array ( 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
	
		/**
		 * Array containing the number of days in each month in a leap year
		 *
		 * @global array $ldays_per_month
		 */
		$ldays_per_month = array ( 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
	
		$date=$this->_date_to_epoch($date);
		
		$thisyear=date("Y",$date);
		$start=$this->_date_to_epoch($event['start']['unix']);
		$finish=$this->_date_to_epoch($event['repeat_finish']['unix']);
		$freq=$event['frequency'];
		$type=$event['type'];
		$thismonth=date("m",$date);

		
		if ($date < $start || ($date > $finish && !empty($finish))) return false;

		if ($type == 'daily') {	
			if ( (floor(($date - $start)/ONE_DAY)%$freq) ) return false;
			return true;
		} else if ($type == 'weekly') {
			$dow  = date("w", $date);
			$dow1 = date("w", $start);
			$isDay = substr($event['days'], $dow, 1);
			$wstart = $start - ($dow1 * ONE_DAY)+ONE_DAY;// week start on monday
			if (floor(($date - $wstart)/604800)%$freq)return false;
			return (strcmp($isDay,"y") == 0);
		}/* else if ($event['EventsRepeat']['type'] == 'monthlyByDay') {
			$dowS = date("w", $start); // start: giorno della settimana 
			$dow  = date("w", $date); // date: giorno della settimana
			// do this comparison first in hopes of best performance
			if ( $dowS != $dow )return false;
			$mthS = date("m", $start); //mese
			$yrS  = date("Y", $start); // anno
			$dayS  = floor(date("d", $start)); // giorno mese
			
			$whichWeek = floor ( ( $daysthismonth - $day ) / 7 ); //
	
			if ((($yr - $yrS)*12 + $mth - $mthS) % $freq)return false;
	
			return ( $whichWeekS == $whichWeek );
		} */else if ($type == 'monthlyByDate') {
			$mthS = gmdate("m", $start);
			$yrS  = gmdate("Y", $start);
	
			$mth  = gmdate("m", $date);
			$yr   = gmdate("Y", $date);
	
			if ((($yr - $yrS)*12 + $mth - $mthS) % $freq)return false;
	
			return (gmdate("d", $date) == gmdate("d", $start));
		} else if ($type == 'yearly') {
			$yrS = gmdate("Y", $start);
			$yr  = gmdate("Y", $date);
	
			if (($yr - $yrS)%$freq)	return false;
	
			return (gmdate("dm", $date) == date("dm", $start));
		} else {
			// unknown repeat type
			return false;
		}
			
		return false;
	}
	
	function edit_event($event,$repeated_event)
	{
		$data_provider=&$this->data_provider;

		if (!empty($event['start']))
		{	
			$start = split('/',$event['start']);
			if(!isset($event['starttime']))$event['starttime']='00:00';
			$data['start'] =$start[2].'-'.$start[1].'-'.$start[0].' '.$event['starttime'].':00';
		}
		if (!empty($event['finish']))
		{
			$finish = split('/',$event['finish']);	
			if(!isset($event['finishtime']))$event['finishtime']='00:00';		
			$data['finish'] =$finish[2].'-'.$finish[1].'-'.$finish[0].' '.$event['finishtime'].':00';
		}
		$data['summary']=$event['summary'];
		$data['allday']=$event['allday'];
		$data['location']=$event['location'];
		$data['description']=$event['description'];
		$data['calendar_id']=$event['calendar_id'];
		$data['gmt_offset']=$event['gmt'];
		
		// Salvataggio
		if (!empty($event['id']))
		{			
			$data_provider->update_event($data,$event['id']);	
		} else {		
			$event['id']=$data_provider->insert_event($data);
		}
		unset($data);

		//$events_repeat=$this->EventsRepeat->findByEventId($this->Event->id);
		//$event=$this->Event->findById($this->Event->id);
		
		
		
		if($repeated_event['type']=='0' ) {
			$data_provider->delete_event_repeat($event['id']);

		}else{
			
			print_r($repeated_event);
			print_r($event['id']);
			$data['event_id']=$event['id'];	
			/*
			switch($repeated_event['type'])
			{
				case 'daily':
					$interval=$repeated_event['frequency'];
				break;
				case 'weekly':
					$interval=$repeated_event['frequency']*7;
				break;
				case 'monthlyByDate':
					$interval=$repeated_event['frequency']*28;
				break;
				case 'yearly':
					$interval=$repeated_event['frequency']*366;
				break;
			}
			// TODO: il controllo non funziona bene sugli eventi non 'allday' 
			// es. 1/1/2007 23:59 ->  2/1/2007 00:01 | daily | frequency = 1  risulta overlapping 
			// graficamente corretto ma concettualmente sbagliato (l'interfaccia non supporta eventi ripetuti overlapping)
			if($interval<$event['Event']['parts']){
				$error['error']=array('errcode'=>'overlapping_repeat','errdesc'=>'Le ripetizioni dell\'evento si sovrappongono');
				die($this->_generateJson($error));
			}*/
			$data['repeat_finish']=null;
			
			if($repeated_event['repeat_finish']!=0 && !empty($repeated_event['repeat_finish_date']))
			{			
				$data['repeat_finish'] = $repeated_event['repeat_finish_date']; /* dd/mm/yyyy */
			}

			$data['frequency']=(int)$repeated_event['frequency'];
			$data['days']=null;
			if($repeated_event['type']=='weekly')
			{
				$days=array('n','n','n','n','n','n','n');
				foreach($repeated_event['days'] as $key=>$item)
				{
					$days[$key]='y';
				}
				$data['days']=implode('',$days);
			}
			$data['type']=$repeated_event['type'];

			$data_provider->set_event_repeat($data,$event['id']);	
									
		}
		
	
	}
	
	function delete_event($id)
	{
		$this->data_provider->delete_event($id);
		die('{"message":"deleted event '.$id.'"}');
		
	}
	/*
	* Aggiorna un evento durante il drag
	*
	*/
	function move_event($event_id, $date_ymd, $view = '', $year = '', $month = '', $day = '')
	{
		$data_provider=&$this->data_provider;
	   	list($event_id) = explode("_",$event_id);
	   	$event=$this->data_provider->get_event($event_id);
		

		$event['start']=$this->_expandDate($event['start']);
		$event['finish']=$this->_expandDate($event['finish']);
		
		$duration=$this->_getEventDuration($event);
		
		$data=$event;
		$data['start']=substr($date_ymd,0,4)."-".substr($date_ymd,4,2)."-".substr($date_ymd,6,2)." ".$event['start']['hour'].":".$event['start']['minute'].":".$event['start']['second'];
		$data['finish']= date("Y-m-d H:i:s",strtotime($data['start'])+$duration);
		
		$data_provider->update_event($data,$event_id);	
		
		$this->get_events($view, $year , $month, $day);
	}
	
	function add_calendar($name,$bgcolor,$textcolor){
		$this->data_provider->insert_calendar(array('name'=>$name,'bgcolor'=>$bgcolor,'textcolor'=>$textcolor));	
	}
	
	function share_calendar($calendar_id,$user_id)
	{
		$this->data_provider->bind_calendar_to_user($calendar_id,$user_id);
	}
	
	function get_calendars()
	{
		
		echo json_encode($this->data_provider->get_calendars());	
		die();
	}


/*
	* Torna il mese precedente rispetto alla richiesta effettuata
	*
	*/
	function _get_previous_month($year,$month)
	{

				
		if ($month == 1) 
		{
			$year--;
			$month = 12;
		} else {
			$month--;
		}
		
		return array($year,$month);
	}
	

	/*
	* Torna il mese successivo rispetto alla richiesta effettuata
	*
	*/
	function _get_next_month($year,$month)
	{

				
		if ($month == 12) 
		{
			$year++;
			$month = 1;
		} else {
			$month++;
		}
		
		return array($year,$month);
	}
	
	function _date_to_epoch ( $utime ) 
	{
		if ( $utime == 0 )
			return 0;
		$T = gmmktime ( 3, 0, 0, gmdate('m',$utime),  gmdate('d',$utime),  gmdate('Y',$utime));

		return $T;
		
	}
		
	function _expandDate($date)
	{
		if(is_null($date)) return null;
		$unix=strtotime($date. "GMT");
		unset($date);		
		$date['unix']=$unix;
		$date['ymd']=gmdate("Ymd",$unix);
		$date['date']=gmdate("d/m/Y",$unix);
		$date['year']=gmdate("Y",$unix);
		$date['month']=gmdate("m",$unix);
		$date['day']=gmdate("d",$unix);
		$date['hour']=gmdate("G",$unix);
		$date['minute']=gmdate("i",$unix);
		$date['second']=gmdate("s",$unix);
		$date['time']=gmdate("G:i",$unix);
		return $date;
	}	
	
	function _getEventDayParts($event)
	{
		
		$tmp_start=gmmktime(0,0,0,$event['start']['month'],$event['start']['day'],$event['start']['year']);
		$tmp_finish=$event['finish']['unix'];
		$parts=ceil(($tmp_finish-$tmp_start)/ONE_DAY);
		if($event['allday']==1)$parts++;
		if($parts==0)$parts++;
		return $parts;
	
	}
	function _getEventDuration($event)
	{
		return $event['finish']['unix']-$event['start']['unix'];

	}
	
	
}
